//
//  Car.m
//  citycar
//
//  Created by Tang JiaQi on 3/15/11.
//  Copyright 2011 HOME. All rights reserved.
//

#import "Car.h"
#import "Coordinate.h"

@implementation CarController

@synthesize owner;

-(id) initWithOwner: (Car*)pCar
{
	if((self = [super init]))
	{
		NSAssert(pCar, @"From CarController: owner is nil");
		owner = pCar;
	}
	return self;
}

-(void) wheelLeft//: (float)ratio
{
	float ratio = 1.f;
	owner.velocity = TsiU::Vec2(-5.f * ratio, owner.velocity.y);
}

-(void) wheelRight//: (float)ratio
{
	float ratio = 1.f;
	owner.velocity = TsiU::Vec2(5.f * ratio, owner.velocity.y);
}

-(void) wheelCentral
{
	owner.velocity = TsiU::Vec2(0.f, owner.velocity.y);
}

-(void) accelerate
{
	float speedY = owner.velocity.y + MAX_SPEED_ACC / GEAR_NUM;
	speedY = fmin(speedY, MAX_SPEED_ACC);
	owner.velocity = TsiU::Vec2(owner.velocity.x, speedY);
}
-(void) deaccelerate
{
	float speedY = owner.velocity.y - MAX_SPEED_ACC / GEAR_NUM;
	speedY = fmax(speedY, MIN_SPEED_ACC);
	owner.velocity = TsiU::Vec2(owner.velocity.x, speedY);
}

@end

@implementation Car

@synthesize velocity;
@synthesize orientation;
@synthesize isFocused;
@synthesize spriteCar;
@synthesize carController;

+(Car*) createNewCar: (CarType)type
{
	switch (type) {
		case ECarType_Car1:
			return [[CarType1 alloc] init];
		case ECarType_Car2:
			return [[CarType2 alloc] init];
		default:
			break;
	}
	return nil;
}

-(id) init;
{
	if((self = [super init]))
	{
		spriteCar = [self type2Resource];
		//self.anchorPoint = ccp(0.5f, 0.5f);
		carController = [[CarController alloc] initWithOwner: self];
		isFocused = NO;
	}
	return self;
}

-(void) updateCar: (ccTime)dt
{
	CGPoint curPos = self.position;
	if(isFocused)
		self.position = ccp(curPos.x + dt * self.velocity.x, curPos.y);
	else
		self.position = ccp(curPos.x + dt * self.velocity.x, curPos.y + dt * self.velocity.y);
}

-(void) reset
{
	self.velocity = TsiU::Vec2(0.f, 0.f);
	self.orientation = TsiU::Vec2(0.f, 1.f);
	self.position = ccp(0.f, 0.f);
}

-(void) wheelLeft//: (float)ratio
{
	[carController wheelLeft];//: ratio];
}

-(void) wheelRight//: (float)ratio
{
	[carController wheelRight];//: ratio];
}

-(void) wheelCentral
{
	[carController wheelCentral];
}

-(void) accelerate
{
	[carController accelerate];
}

-(void) deaccelerate
{
	[carController deaccelerate];
}

-(CCSprite* ) type2Resource
{
	return nil;
}

-(CGPoint) position
{
	return [Coordinate screenToRealWorld: spriteCar.position];
}

-(void) setPosition: (CGPoint) pos
{
	spriteCar.position = [Coordinate realWorldToScreen: pos];
}

-(TsiU::Vec2) velocity
{
	return velocity;
}

-(void) setVelocity: (TsiU::Vec2)vel
{
	velocity = vel;//ccp(vel.x, vel.y * self.orientation.y);
}

-(TsiU::Vec2) orientation
{
	return orientation;
}

-(void) setOrientation: (TsiU::Vec2)ori
{
	orientation = ori;
	TsiU::Vec3 yAxis = TsiU::Vec3::YUNIT;
	TsiU::Vec3 ori3D = TsiU::Vec3(ori.x, ori.y, 0.f);
	TsiU::Vec3 crossProd = yAxis.CrossProduct(ori3D);
	float angle = TsiU::Math::ACos(yAxis.DotProduct(ori3D));
	if(crossProd.z > 0.f)
		angle *= -1;
	spriteCar.rotation = angle * TsiU::Math::kTO_DEGREE;
}
		
-(void) setFocused: (BOOL) val
{
	isFocused = val;
}

@end

@implementation CarType1

-(CCSprite*) type2Resource
{
	[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"grossini.plist"];
	CCSpriteSheet* spriteSheetCar = [CCSpriteSheet spriteSheetWithFile:@"grossini.png"];
	CCSprite* newSpriteCar = [CCSprite spriteWithSpriteFrameName:@"grossini_dance_01.png"];
	[spriteSheetCar addChild:newSpriteCar];
	[self addChild:spriteSheetCar];
	NSMutableArray *animFrames = [NSMutableArray array];
	for(int i = 1; i < 15; i++) {
		CCSpriteFrame *frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"grossini_dance_%02d.png",i]];
		[animFrames addObject:frame];
	}
	CCAnimation *animation = [CCAnimation animationWithName:@"dance" frames:animFrames];
	[newSpriteCar runAction:[CCRepeatForever actionWithAction: [CCAnimate actionWithDuration:2.8f animation:animation restoreOriginalFrame:NO]]];
	return newSpriteCar;
}	

@end

@implementation CarType2

-(CCSprite*) type2Resource
{
	CCSprite* newSpriteCar = [CCSprite spriteWithFile: @"Express_car.png"];
	return newSpriteCar;
}	

@end



